<?php
/**
 * Created by PhpStorm.
 * User: jaylen
 * Date: 2020-10-27
 * Time: 16:35
 */

namespace app\common\model;


use app\common\exception\ParameterException;
use app\common\exception\ProductException;
use app\common\model\traits\HandleShopProduct;
use app\common\model\traits\HandleShopProductShowData;
use app\common\validate\IDMustBeRequire;
use think\model\concern\SoftDelete;
use app\admin\validate\ShopProduct as Validate;
use app\common\model\ShopProductSpecsProperty as ShopSpecsPropertyModel;

class ShopProduct extends BaseModel
{
    protected $hidden = ['update_time','delete_time'];

    // 使用软删除
    use SoftDelete;
    protected $deleteTime = 'delete_time';

    public function property()
    {
        return $this->hasMany('ShopProductProperty','product_id','id');
    }

    public function specs()
    {
        return $this->hasMany('ShopProductSpecs','product_id','id');
    }

    public function parameters()
    {
        return $this->hasMany('ShopProductParameters', 'product_id','id');
    }

    public function category()
    {
        return $this->belongsTo('ShopCategory', 'category_id', 'id');
    }

    public function setMainImageAttr($value, $data)
    {
        if (empty($value)) {
            return json_encode([], JSON_UNESCAPED_UNICODE);
        } else {
            return json_encode($value, JSON_UNESCAPED_UNICODE);
        }
    }

    public function getMainImageAttr($value, $data)
    {
        return [
            'value' => json_decode($value, true),
            'prefix' => $this->prefixImgUrl($value, true)
        ];
    }

    public function setKeywordAttr($value, $data)
    {
        return remove_xss($value);
    }

    public function setDescAttr($value, $data)
    {
        return remove_xss($value);
    }

    use HandleShopProduct;
    use HandleShopProductShowData;

    /**
     * 获取图鸟商店商品的分页数据
     * @param array $params
     * @return mixed
     */
    public static function getPaginationList(array $params)
    {
        static::validatePaginationData($params);

        $static = new static();

        $static = $static->order(['category_id' => 'ASC', 'sort'=>'ASC']);

        $static = $static->with(['specs' => function($query) {
            $query->with(['property' => function($query) {
                $query->with(['property']);
            }]);
        }, 'category']);

        foreach ($params as $name => $value) {
            $value = !is_array($value) ? trim($value) : $value;
            switch ($name) {
                case 'title':
                    if (!empty($value)) {
                        $like_text = '%' . $value . '%';
                        $static = $static->whereLike('title', $like_text);
                    }
                    break;
                case 'virtual_product':
                    if ($value === '0' || !empty($value)) {
                        $static = $static->where('virtual_product', '=', intval($value));
                    }
                    break;
                case 'category_id':
                    if (!empty($value)) {
                        $static = $static->where('category_id', '=', intval($value));
                    }
                    break;
                case 'keyword':
                    if (!empty($value)) {
                        $like_text = '%' . $value . '%';
                        $static = $static->whereLike('keyword', $like_text);
                    }
                    break;
                case 'sort_order':
                    if (!empty($value)) {
                        $static = $static->order($params['sort_prop'], $value == 'descending' ? 'desc' : 'asc');
                    }
                    break;
            }
        }

        return $static
            ->paginate([
                'page' => $params['page'],
                'list_rows' => $params['limit']
            ], false);
    }

    /**
     * 获取全部的商店商品标题信息
     * @return array
     */
    public static function getAllProductTitle($title)
    {
        $product = static::with(['category'])
            ->where([['title','like','%'.$title.'%']])
            ->field('id,category_id,title')
            ->order(['category_id' => 'DESC', 'sort' => 'ASC'])
            ->select();

        if ($product->isEmpty()) {
            return [];
        }

        $product = $product->toArray();
        $product_data = [];

        // 先对数据进行预处理
        foreach ($product as $p_item) {
            $product_data[] = [
                'id' => $p_item['id'],
                'title' => $p_item['category']['title'] . '-' . $p_item['title'],
            ];
        }


        return $product_data;
    }

    /**
     * 根据id获取商品的详细内容
     * @param $id
     * @return array
     */
    public static function getProductByID($id)
    {
        $validate = new IDMustBeRequire();
        if (!$validate->check(['id'=>$id])) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        $static = new static();

        $static = $static->with(['property', 'specs' => function($query) {
            $query->with(['property']);
        }, 'parameters'])
            ->find($id);

        return $static ? $static->toArray() : [];
    }

    /**
     * 获取商品和对应规格数据
     * @param $data
     * @return array
     */
    public static function getAllProductSpecsData($data)
    {
        // 获取商品的规格数据
        $product = static::with(['specs' => function($query) {
            $query->with(['property'])
                ->field('id,product_id');
        }])
            ->where([['title','like','%'.$data['title'].'%'],['status','=',1]])
            ->field('id,title')
            ->order(['recomm' => 'DESC','sort' => 'ASC'])
            ->select();
        if ($product->isEmpty()) {
            throw new ProductException([
                'msg' => '商品列表数据为空'
            ]);
        }

        $product_data = $product->toArray();

        $data = self::generaProductSpecsOptionsGroup($product_data);

        return $data;
    }

    /**
     * 添加商品数据
     * @param array $data
     * @return bool
     */
    public static function addProduct(array $data)
    {
        $validate = new Validate();
        if (!$validate->scene('add')->check($data)) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        // 处理前端传过来的数据
        $submit_data = self::splitSubmitData($data);

        $static = new static();
        $static->startTrans();

        try {

            // 先把基本数据存入数据库
            $static->allowField(['title','main_image','category_id','keyword','desc','content','virtual_product','virtual_sales_volume','sort','recomm','status'])
                ->save($submit_data['base']);
            $static->refresh();

            // 得到商品id
            $product_id = $static->id;

            // 生成property数据
            $property_data = self::generatePropertyData($product_id, $submit_data['property']);
            // 生成specs数据
            $specs_data = self::generateSpecsData($product_id, $property_data['prop']??[], $submit_data['specs']);

            // 保存property数据
            if (!empty($submit_data['property'])) {
                $static->property()->saveAll($property_data['data']);
            }

            // 保存specs数据
            if (!empty($submit_data['specs'])) {
                $static->specs()->saveAll($specs_data['data']);

                // 保存规格与属性之间的数据
                (new ShopSpecsPropertyModel())->saveAll($specs_data['property']);
            }

            // 保存parameters数据
            if (!empty($submit_data['parameters'])) {
                $static->parameters()->saveAll($submit_data['parameters']);
            }

            $static->commit();
        } catch (\Exception $e) {
            $static->rollback();
            return false;
        }

        return true;
    }

    /**
     * 编辑商店商品数据
     * @param array $data
     * @return bool
     */
    public static function editProduct(array $data)
    {
        $validate = new Validate();
        if (!$validate->scene('edit')->check($data)) {
            throw new ParameterException([
                'msg' => $validate->getError(),
            ]);
        }

        // 处理前端传过来的数据
        $submit_data = self::splitSubmitData($data);
        // 得到商品id
        $product_id = $data['id'];
        $needDeleteFile = [];

        $static = static::find($data['id']);
        $static->startTrans();

        try {

            $old_product_data = $static->toArray();
            $needDeleteFile = self::deleteOldProductFileData($old_product_data, $data);

            // 先把基本数据更新到数据库
            $static->allowField(['id','title','main_image','category_id','keyword','desc','content','virtual_product','virtual_sales_volume','sort','recomm','status'])
                ->save($submit_data['base']);

            // 删除旧的的商品属性和规格数据
            self::deleteOldPropertySpecs($product_id);

            // 生成property数据
            $property_data = self::generatePropertyData($product_id, $submit_data['property']);
            // 生成specs数据
            $specs_data = self::generateSpecsData($product_id, $property_data['prop']??[], $submit_data['specs']);

            // 保存property数据
            if (!empty($submit_data['property'])) {
                $static->property()->saveAll($property_data['data']);
            }

            // 保存specs数据
            if (!empty($submit_data['specs'])) {
                $static->specs()->saveAll($specs_data['data']);

                // 保存规格与属性之间的数据
                (new ShopSpecsPropertyModel())->saveAll($specs_data['property']);
            }

            // 保存parameters数据
            if (!empty($submit_data['parameters'])) {
                $static->parameters()->saveAll($submit_data['parameters']);
            }

            $static->commit();
        } catch (\Exception $e) {
            $static->rollback();
            return false;
        }

        if (!empty($needDeleteFile)) {
            delFile($needDeleteFile);
        }

        return true;
    }



}